import { Request, Response } from 'express';
import jobService from '@/services/monitor/job.service';
import ApiResponse from '@/utils/api/api-response.util';
import { getLogger } from '@/utils/logger';
import ExcelUtil from '@/utils/excel/excel.util';
import { Log, BusinessType } from '@/decorators/Log';
import { AuthRequest } from '@/types';

// 创建模块专用的日志记录器
const consoleLogger = getLogger("job-controller");
const logger = getLogger("job-controller", {
	console: false,
});

/**
 * 定时任务控制器
 */
class JobController {
  /**
   * 获取定时任务列表
   * @param req 请求对象
   * @param res 响应对象
   */
  public async list(req: Request, res: Response) {
    try {
      // 请求日志
      consoleLogger.info("获取定时任务列表请求", {
        query: req.query,
        operator: req.user?.userName || 'unknown',
      });
      
      const { pageNum = 1, pageSize = 10, ...query } = req.query;
      
      // 转换为数字
      const pNum = parseInt(pageNum as string, 10);
      const pSize = parseInt(pageSize as string, 10);
      
      const { rows, count } = await jobService.getJobListPaged({
        pageNum: pNum,
        pageSize: pSize,
        ...query
      });
      
      // 结果日志
      logger.info("获取定时任务列表成功", {
        response: {
          total: count,
          count: rows.length,
        },
        operator: req.user?.userName || 'unknown',
      });

      ApiResponse.successWithTable(res, rows, count, "查询成功");
    } catch (error) {
      // 详细的错误日志
      consoleLogger.error(`获取任务列表失败: ${error instanceof Error ? error.message : String(error)}`, {
        requestData: {
          query: req.query,
        },
        operator: req.user?.userName || 'unknown',
        stack: error instanceof Error ? error.stack : undefined
      });
      if (!res.headersSent) {
        ApiResponse.error(res, error instanceof Error ? error.message : '查询失败');
      }
    }
  }

  /**
   * 获取定时任务详细信息
   * @param req 请求对象
   * @param res 响应对象
   */
  public async getInfo(req: Request, res: Response) {
    try {
      const jobId = parseInt(req.params.jobId, 10);
      
      // 请求日志
      consoleLogger.info("获取定时任务详情请求", {
        params: req.params,
        jobId,
        operator: req.user?.userName || 'unknown',
      });
      
      const data = await jobService.selectJobById(jobId);
      
      if (!data) {
        consoleLogger.warn('获取定时任务详情 - 任务不存在', { jobId });
        ApiResponse.error(res, '任务不存在', 404);
        return;
      }
      
      // 结果日志
      logger.info("获取定时任务详情成功", {
        response: {
          jobId,
          data,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.success(res, data);
    } catch (error) {
      // 详细的错误日志
      consoleLogger.error(`获取任务详情失败: ${error instanceof Error ? error.message : String(error)}`, {
        requestData: {
          params: req.params,
        },
        operator: req.user?.userName || 'unknown',
        stack: error instanceof Error ? error.stack : undefined
      });
      if (!res.headersSent) {
        ApiResponse.error(res, error instanceof Error ? error.message : '查询失败');
      }
    }
  }

  /**
   * 新增定时任务
   * @param req 请求对象
   * @param res 响应对象
   */
  @Log({ title: '定时任务', businessType: BusinessType.INSERT })
  public async add(req: AuthRequest, res: Response) {
    try {
      const job = req.body;
      
      // 请求日志
      consoleLogger.info("新增定时任务请求", {
        body: req.body,
        operator: req.user?.userName || 'unknown',
      });
      
      job.createBy = req.user?.userName;

      const jobId = await jobService.insertJob(job);
      
      // 结果日志
      logger.info("新增定时任务成功", {
        response: {
          jobId,
          jobName: job.jobName,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.success(res, null, "操作成功");
    } catch (error) {
      // 详细的错误日志
      consoleLogger.error(`新增任务失败: ${error instanceof Error ? error.message : String(error)}`, {
        requestData: {
          body: req.body,
        },
        operator: req.user?.userName || 'unknown',
        stack: error instanceof Error ? error.stack : undefined
      });
      if (!res.headersSent) {
        ApiResponse.error(res, `新增任务'${req.body.jobName}'失败，${error instanceof Error ? error.message : '未知错误'}`);
      }
    }
  }

  /**
   * 修改定时任务
   * @param req 请求对象
   * @param res 响应对象
   */
  @Log({ title: '定时任务', businessType: BusinessType.UPDATE })
  public async edit(req: AuthRequest, res: Response) {
    try {
      const job = req.body;
      
      // 请求日志
      consoleLogger.info("修改定时任务请求", {
        body: req.body,
        operator: req.user?.userName || 'unknown',
      });
      
      job.updateBy = req.user?.userName;

      const rows = await jobService.updateJob(job);
      
      // 结果日志
      logger.info("修改定时任务成功", {
        response: {
          jobId: job.jobId,
          jobName: job.jobName,
          rows,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.success(res, null, "操作成功");
    } catch (error) {
      // 详细的错误日志
      consoleLogger.error(`修改任务失败: ${error instanceof Error ? error.message : String(error)}`, {
        requestData: {
          body: req.body,
        },
        operator: req.user?.userName || 'unknown',
        stack: error instanceof Error ? error.stack : undefined
      });
      if (!res.headersSent) {
        ApiResponse.error(res, `修改任务'${req.body.jobName}'失败，${error instanceof Error ? error.message : '未知错误'}`);
      }
    }
  }

  /**
   * 定时任务状态修改
   * @param req 请求对象
   * @param res 响应对象
   */
  @Log({ title: '定时任务', businessType: BusinessType.UPDATE })
  public async changeStatus(req: AuthRequest, res: Response) {
    try {
      const job = req.body;
      
      // 请求日志
      consoleLogger.info("修改定时任务状态请求", {
        body: req.body,
        operator: req.user?.userName || 'unknown',
      });
      
      const rows = await jobService.changeStatus(job);
      
      // 结果日志
      logger.info("修改定时任务状态成功", {
        response: {
          jobId: job.jobId,
          status: job.status,
          rows,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.success(res, null, "操作成功");
    } catch (error) {
      // 详细的错误日志
      consoleLogger.error(`修改任务状态失败: ${error instanceof Error ? error.message : String(error)}`, {
        requestData: {
          body: req.body,
        },
        operator: req.user?.userName || 'unknown',
        stack: error instanceof Error ? error.stack : undefined
      });
      if (!res.headersSent) {
        ApiResponse.error(res, error instanceof Error ? error.message : '操作失败');
      }
    }
  }

  /**
   * 定时任务立即执行一次
   * @param req 请求对象
   * @param res 响应对象
   */
  @Log({ title: '定时任务', businessType: BusinessType.UPDATE })
  public async run(req: AuthRequest, res: Response) {
    try {
      const job = req.body;
      
      // 请求日志
      consoleLogger.info("执行定时任务请求", {
        body: req.body,
        operator: req.user?.userName || 'unknown',
      });
      
      const result = await jobService.run(job);
      
      // 结果日志
      logger.info("执行定时任务结果", {
        response: {
          jobId: job.jobId,
          result,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      if (result) {
        ApiResponse.success(res);
      } else {
        consoleLogger.warn('执行定时任务失败: 任务不存在或已过期', { jobId: job.jobId });
        ApiResponse.error(res, '任务不存在或已过期！');
        return;
      }
    } catch (error) {
      // 详细的错误日志
      consoleLogger.error(`执行任务失败: ${error instanceof Error ? error.message : String(error)}`, {
        requestData: {
          body: req.body,
        },
        operator: req.user?.userName || 'unknown',
        stack: error instanceof Error ? error.stack : undefined
      });
      if (!res.headersSent) {
        ApiResponse.error(res, error instanceof Error ? error.message : '操作失败');
      }
    }
  }

  /**
   * 删除定时任务
   * @param req 请求对象
   * @param res 响应对象
   */
  @Log({ title: '定时任务', businessType: BusinessType.DELETE })
  public async remove(req: AuthRequest, res: Response) {
    try {
      const jobIds = req.params.jobIds.split(',').map((id: string) => parseInt(id, 10));
      const operator = req.user?.userName || 'admin';
      
      // 请求日志
      consoleLogger.info("删除定时任务请求", {
        params: req.params,
        jobIds,
        operator,
      });
      
      await jobService.deleteJobByIds(jobIds);
      
      // 结果日志
      logger.info("删除定时任务成功", {
        response: {
          jobIds,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.success(res);
    } catch (error) {
      // 详细的错误日志
      consoleLogger.error(`删除任务失败: ${error instanceof Error ? error.message : String(error)}`, {
        requestData: {
          params: req.params,
        },
        operator: req.user?.userName || 'unknown',
        stack: error instanceof Error ? error.stack : undefined
      });
      if (!res.headersSent) {
        ApiResponse.error(res, error instanceof Error ? error.message : '操作失败');
      }
    }
  }

  /**
   * 导出定时任务
   * @param req 请求对象
   * @param res 响应对象
   */
  @Log({ title: '定时任务', businessType: BusinessType.EXPORT })
  public async export(req: Request, res: Response) {
    try {
      // 请求日志
      consoleLogger.info("导出定时任务请求", {
        query: req.query,
        operator: req.user?.userName || 'unknown',
      });
      
      const { pageNum, pageSize, ...query } = req.query;
      const { rows } = await jobService.getJobListPaged({
        pageNum: 1,
        pageSize: Number.MAX_SAFE_INTEGER,
        ...query
      });
      
      const fields = [
        { header: '任务编号', key: 'jobId', width: 10 },
        { header: '任务名称', key: 'jobName', width: 20 },
        { header: '任务组名', key: 'jobGroup', width: 15 },
        { header: '调用目标字符串', key: 'invokeTarget', width: 30 },
        { header: 'cron表达式', key: 'cronExpression', width: 20 },
        { header: '状态', key: 'status', width: 10, formatter: (v: string) => v === '0' ? '正常' : '暂停' },
        { header: '创建时间', key: 'createTime', width: 20, type: 'datetime' }
      ];
      
      await ExcelUtil.exportToResponse(
        res,
        rows,
        fields,
        `job_${Date.now()}`,
        '定时任务'
      );
      
      // 结果日志
      logger.info("导出定时任务成功", {
        response: {
          count: rows.length,
        },
        operator: req.user?.userName || 'unknown',
      });
    } catch (error) {
      // 详细的错误日志
      consoleLogger.error(`导出定时任务失败: ${error instanceof Error ? error.message : String(error)}`, {
        requestData: {
          query: req.query,
        },
        operator: req.user?.userName || 'unknown',
        stack: error instanceof Error ? error.stack : undefined
      });
      if (!res.headersSent) {
        ApiResponse.error(res, '导出定时任务失败', 500);
      }
    }
  }
}

export default new JobController(); 